package com.runvp.common.model.tcp;

import com.alibaba.fastjson.JSONObject;
import com.runvp.common.hex.HexConvert;
import com.runvp.common.util.enc.aes128gcm.Aes128GcmUtils;
import lombok.Getter;
import lombok.ToString;

import java.io.Serializable;
import java.util.Date;

@Getter
@ToString
public class MessageParseBody implements Serializable{


    private static final long serialVersionUID = -6724284223730476975L;
    /**
     * 协议头 0x3A,0x3A,ASCII 码两个冒号":"
     */
    private String head ;
    /**
     * TYPE：数据类型，
     * ◼ 服务器往设备下发为:0x01
     * ◼ 设备应答服务器指令为:0x02
     * ◼ 设备请求服务器为:0x03
     * ◼ 服务器应答设备请求为:0x04
     */
    private String type;
    /**
     * ⚫ CMD:指令名
     */
    private String cmd ;
    /**
     * 设备 ID，在设备登录完成后，每次和服务器进行交互数据时，携带服务器下发的
     * ID 值。
     */
    private String did;
    /**
     * 版本，版本用于区别不同数据交互的加密数据信息 KEY 和 IV
     */
    private String version = "01";
    /**
     * 业务参数的长度值，此处指的是业务参数的长度，不包括 TAG 的 16 字节数据
     */
    private String length;
    /**
     * 业务参数，业务参数原始数据采用 json 保存，之后再通过"AES-128-GCM"加
     * 密
     */
    private String body;

    /**
     * gcm 产生的 TAG 标识数据。
     */
    private String tag ;

    /**
     * 使用时间
     */
    private Date time;


    private String terminalId;

    private String ty;
    /**
     * 源报文
     */
    private String sourceMsg;
    /**
     * 批次号
     */
    private String batchNo;

    public String buildCmd(){
        StringBuilder sb = new StringBuilder();
        sb.append(head);
        sb.append(type);
        sb.append(cmd);
        sb.append(did);
        sb.append(version);
        sb.append(length);
        sb.append(body);
        sb.append(tag);
        return sb.toString();
    }

    public MessageParseBody setTy(String ty) {
        this.ty = ty;
        return this;
    }

    public MessageParseBody setTerminalId(String terminalId) {
        this.terminalId = terminalId;
        return this;
    }

    public MessageParseBody setHead(String head) {
        this.head = head;
        return this;
    }

    public MessageParseBody setType(String type) {
        this.type = type;
        return this;
    }

    public MessageParseBody setCmd(String cmd) {
        this.cmd = cmd;
        return this;
    }

    public MessageParseBody setDid(String did) {
        this.did = did;
        return this;
    }

    public MessageParseBody setVersion(String version) {
        this.version = version;
        return this;
    }

    public MessageParseBody setLength(String length) {
        this.length = length;
        return this;
    }

    public MessageParseBody setBody(String body) {
        this.body = body;
        return this;
    }
    /**
     * 加密结果体
     * @return str
     */
    public String encBody(JSONObject map){
        StringBuilder sb = new StringBuilder(Aes128GcmUtils.getInstance().encrypt(JSONObject.toJSONString(map)));
        return sb.toString().toUpperCase();
    }
    public MessageParseBody buildRes(){
        String tempBody = this.body;
        this.body = tempBody.substring(0,tempBody.length()-32);
        this.length = HexConvert.numberTen2Hex(this.body.length()/2);
        if(this.length.length() < 4){
            this.length = "00"+this.length;
        }
        this.tag = tempBody.replace(this.body,"");
        return this;
    }

    public MessageParseBody setTag(String tag) {
        this.tag = tag;
        return this;
    }

    public MessageParseBody setTime(Date time) {
        this.time = time;
        return this;
    }

    public MessageParseBody setSourceMsg(String sourceMsg) {
        this.sourceMsg = sourceMsg;
        return this;
    }

    public MessageParseBody setBatchNo(String batchNo) {
        this.batchNo = batchNo;
        return this;
    }

    public MessageParseBody() {
        this.time = new Date();
    }

    public MessageParseBody(String type, String cmd) {
        this.head = "3A3A";
        this.type = type;
        this.cmd = cmd;
    }
}
